﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Insteon.Commands.Insteon
{
    internal class StandardCommand : Command
    {
        internal readonly InsteonAddress To;
        internal readonly Flags Flags;
        internal readonly byte Command1;
        internal readonly byte Command2;

        internal StandardCommand(Flags.MessageType Type, InsteonAddress To, byte Command1, byte Command2)
        {
            Flags = new Flags(Type, false);
            if (To == null || Flags == null)
            {
                throw new Exception("from, to, or flags cannot be null");
            }
            this.To = To;
            this.Command1 = Command1;
            this.Command2 = Command2;
            buffer = new byte[8];
            buffer[0] = 2;
            buffer[1] = (byte)IMCommand.IMCommands.Command;
            buffer[2] = To.High;
            buffer[3] = To.Mid;
            buffer[4] = To.Low;
            buffer[5] = Flags.BinFlags;
            buffer[6] = Command1;
            buffer[7] = Command2;
        }

        internal StandardCommand(InsteonAddress To, byte Command1, byte Command2) 
        {
            this.Flags = new Flags(Flags.MessageType.Direct, false);
            if (To == null || Flags == null)
            {
                throw new Exception("from, to, or flags cannot be null");
            }
            this.To = To;
            this.Command1 = Command1;
            this.Command2 = Command2;
            buffer = new byte[8];
            buffer[0] = 2;
            buffer[1] = (byte)IMCommand.IMCommands.Command;
            buffer[2] = To.High;
            buffer[3] = To.Mid;
            buffer[4] = To.Low;
            buffer[5] = Flags.BinFlags;
            buffer[6] = Command1;
            buffer[7] = Command2;


        }

        public override string ToString()
        {
            return PrintCommonMessage(this.SentTime, Number, this, To, null, Flags, Command1, Command2, null);
        }

        internal override bool IsResponse(Messages.Message Message)
        {
            //modem response
            if (Message is Messages.Insteon.StandardResponse)
            {
                Messages.Insteon.StandardResponse Mess = (Messages.Insteon.StandardResponse)Message;

                if ((Mess.To == this.To)
                        && (Mess.Flags.Type == Flags.MessageType.Direct)
                        && (Mess.Command1 == this.Command1)
                        && (Mess.Command2 == this.Command2))
                {
                    ModemCompleted = true;
                    ModemResponse = Message;
                    if (Mess.Status.Status == ResponseStatus.Statuses.NAK){
                        this.Fail();
                    }
                    return true;
                }
            }

            //device response
            if (Message is Messages.Insteon.StandardMessage)
            {
                Messages.Insteon.StandardMessage Mess = (Messages.Insteon.StandardMessage)Message;
                if ((Mess.From == this.To)
                        && ((Mess.Flags.Type == Flags.MessageType.ACKofDirect) || (Mess.Flags.Type == Flags.MessageType.NAKofDirect)))
                {
                    if ((Mess.Command1 == this.Command1)
                        && (Mess.Command2 == this.Command2))
                    {
                        DeviceCompleted = true;
                        DeviceResponse = Message;
                        if (Mess.Flags.Type == Flags.MessageType.ACKofDirect)
                        {
                            this.Succeed();
                        }
                        else
                        {
                            this.Fail();
                        }
                        return true;
                    }
                    else
                    {
                        if (this.Command1 == 0x19) //light state request will not echo command2
                        {
                            DeviceCompleted = true;
                            DeviceResponse = Message;
                            this.Succeed();
                            return true;
                        }
                    }
                }
            }
            return false;
        }
    }
}
